/*
 * Copyright 2011 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.google.paymentexpress.server;

import java.io.IOException;
import java.io.PrintWriter;
import java.security.InvalidKeyException;
import java.util.List;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.oauth.jsontoken.JsonToken;
import net.oauth.jsontoken.JsonTokenParser;
import net.oauth.jsontoken.crypto.HmacSHA256Verifier;
import net.oauth.jsontoken.crypto.SignatureAlgorithm;
import net.oauth.jsontoken.crypto.Verifier;
import net.oauth.jsontoken.discovery.VerifierProvider;
import net.oauth.jsontoken.discovery.VerifierProviders;

import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.apache.velocity.exception.MethodInvocationException;
import org.apache.velocity.exception.ParseErrorException;
import org.apache.velocity.exception.ResourceNotFoundException;

import com.google.common.collect.Lists;
import com.google.paymentexpress.jwt.Cart;
import com.google.paymentexpress.jwt.FullWalletRequest;
import com.google.paymentexpress.jwt.IgnoreAudience;
import com.google.paymentexpress.jwt.LineItem;
import com.google.paymentexpress.jwt.MaskedWalletRequest;
import com.google.paymentexpress.jwt.MaskedWalletResponse;
import com.google.paymentexpress.server.beans.Order;
import com.google.paymentexpress.server.config.Config;

/**
 * 
 * @author pying(peng ying)
 *
 */
public class ConfirmServlet extends HttpServlet {

  /**
   * 
   */
  private static final long serialVersionUID = 2294124125211846176L;
  
  public void doGet(HttpServletRequest req, HttpServletResponse resp){
    
  }
  
  public void doPost(HttpServletRequest req, HttpServletResponse resp){
    String origin = Config.getDomain(req);
    
    //Get post params
    String drink = req.getParameter("drink");
    String size = req.getParameter("size");
    String milk = req.getParameter("milk");
    String pickup = req.getParameter("pickup");
    String total = req.getParameter("formTotal");
    
    Order order = new Order(drink, size, milk, pickup, total);
    
    String request = req.getParameter("maskedWalletJWT");
    
    //Convert JWT to JavaObjects
    try {
      final Verifier hmacVerifier = new HmacSHA256Verifier(Config.MERCHANT_SECRET.getBytes());
      VerifierProvider hmacLocator = new VerifierProvider() {
        
        public List<Verifier> findVerifier(String id, String key){
          return Lists.newArrayList(hmacVerifier);
        }

      };
      
      VerifierProviders locators = new VerifierProviders();
      locators.setVerifierProvider(SignatureAlgorithm.HS256, hmacLocator); 
      
      JsonTokenParser parser = new JsonTokenParser(locators, new IgnoreAudience());
      JsonToken jwt = parser.deserialize(request);
      
      MaskedWalletResponse mwResponse = new MaskedWalletResponse(jwt);
      
      //Create the change information maskedWalletRequest
      MaskedWalletRequest maskedWalletRequest = new MaskedWalletRequest(Config.MERCHANT_ID, Config.MERCHANT_SECRET, MaskedWalletRequest.Select.PAY_SHIP, mwResponse.getGoogle_transaction_id());
      maskedWalletRequest.setOrigin(origin);
      
      String desc = drink + " " + size + " " + milk;
      LineItem item = new LineItem( desc, 1, new Double(total), Config.CURRENCY);
      Cart cart = new Cart(Config.CURRENCY);
      cart.addItem(item);
      
      FullWalletRequest fullWalletRequest = new FullWalletRequest(Config.MERCHANT_ID, Config.MERCHANT_SECRET, cart, mwResponse.getGoogle_transaction_id());
      fullWalletRequest.setOrigin(origin);
      
      Velocity.setProperty("runtime.log.logsystem.class", "org.apache.velocity.runtime.log.NullLogChute");
      
      // Escape HTML
      Velocity.setProperty("eventhandler.referenceinsertion.class", "org.apache.velocity.app.event.implement.EscapeHtmlReference");
      Velocity.setProperty("eventhandler.escape.html.match", "/.*/");
      Velocity.init();

      VelocityContext context = new VelocityContext();
      context.put("pay", mwResponse.getSelection().getPay());
      context.put("ship", mwResponse.getSelection().getShip());
      context.put("order", order);
      context.put("maskedJWT", maskedWalletRequest.generateJWT());
      context.put("fullWalletJWT", fullWalletRequest.generateJWT());
      context.put("walletJSUrl", Config.WALLET_JS_URL);
      
      PrintWriter pw;
      pw = resp.getWriter();
      Velocity.mergeTemplate("confirm.vm","UTF-8", context, pw);
      pw.flush();
      pw.close();
      
    } catch (InvalidKeyException e) {
      e.printStackTrace();
    } catch (ResourceNotFoundException e) {
      e.printStackTrace();
    } catch (ParseErrorException e) {
      e.printStackTrace();
    } catch (MethodInvocationException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}
